<?php

class GmToolsGiftCodeService
{

    /**
     * @var GmToolsGiftCodeService
     */
    private static $instance;

    /**
     * 单例函数
     * @return GmToolsGiftCodeService
     */
    public static function get()
    {
        if (!self::$instance) {
            self::$instance = new GmToolsGiftCodeService();
        }
        return self::$instance;
    }

    /**
     * VisitInitService constructor.
     */
    private function __construct()
    {
        $this->randomDictionary = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
            '2', '3', '4', '5', '6', '7', '8', '9');
        $this->maxLen = count($this->randomDictionary);
    }

    /**
     * 获取礼包码6位前缀
     * @return string 礼包码6位前缀
     */
    public function generateGiftCodePrefix()
    {
        $_code = '';
        for ($i = 0; $i < 6; $i++) {
            $_code .= $this->randomDictionary[rand(0, $this->maxLen - 1)];
        }
        return $_code;
    }

    /**
     * 获取礼包码10位后缀
     * @return string 礼包码10位后缀
     */
    public function generateGiftCodeSuffix()
    {
        $_code = '';
        for ($i = 0; $i < 10; $i++) {
            $_code .= $this->randomDictionary[rand(0, $this->maxLen - 1)];
        }
        return $_code;
    }

    /**
     * 获取批次ID
     * @return string
     */
    public function generateBatchId()
    {
        /** @var GmBatchVoList $_gmBatchVoList */
        $_gmBatchVoList = SzPersister::get()->getVoList(0, GameConst::ORM_NAME_GM_TOOLS_BATCH);
        while (true) {
            $_prefix = $this->generateGiftCodePrefix();
            /** @var GmBatchVo $_gmBatchVo */
            $_gmBatchVo = $_gmBatchVoList->getElement($_prefix, false);
            if (!$_gmBatchVo) {
                return $_prefix;
            }
        }
        return '';
    }

    /**
     * 创建一批次的礼包码
     * @param $params
     * @return array
     * @throws SzException
     */
    public function createBatchGiftCode($params)
    {
        /*
            "params": {
                "EndTime": "2017-04-01 12:00:00",（礼包到期时间）
                "StartTime": "2017-03-01 12:00:00",（礼包开始时间）
                "Name": "奖励1",（礼包名称）
                "Comment": "XXXXXX",（礼包说明）
                "Limit": 1, （1表示只有一个帐号领取，0表示多个帐号可以领取）
                "items": {"111234":10,"883747":19},,（物品id：物品数量）
                "AreaList": "all",（区服）
                "Count": 10（礼包数量，这个字段只有limit为1才有用，如果一个礼包可以多个帐号领取，那么数量是没用意义的）
                }
            }
         */
        $_res = array();
        $EndTime = $params['EndTime'];
        $StartTime = $params['StartTime'];
        $Name = $params['Name'];
        $Comment = $params['Comment'];
        $Limit = $params['Limit'];
        $items = $params['items'];
        $Count = $params['Count'];

        $StartTime = strtotime($StartTime);
        if (!$StartTime)
            throw new SzException(25004);
        $EndTime = strtotime($EndTime);
        if (!$EndTime)
            throw new SzException(25004);
        $_items = array();
        foreach ($items as $itemId => $count) {
            $_itemConfig = SzConfig::get()->loadAppConfig(ModuleItemConst::CONFIG_ITEM_DEFS, $itemId, true, false);
            if (!$_itemConfig)
                throw new SzException(25008, array($itemId));
            $_entityId = EntityService::get()->buildEntityId(72, $_itemConfig['moduleId'], $itemId);
            $_items[$_entityId] = $count;
        }

        list($_batchId, $_giftCodeArr) = $this->generateGiftCode($Name, $Comment, $Limit, $StartTime, $EndTime, $_items, 1, $Count, 0);
        $_res['batch_id'] = $_batchId;
        $_res['count'] = $Count;
        $_res['has_active'] = 0;
        $_res['has_used_num'] = 0;
        $_res['name'] = $Name;
        $_res['limit'] = $Limit;
        $_res['is_active'] = '1';
        $_res['can_use'] = 1;
        $_res['batch_list'] = array();
        $_res['start_time'] = $params['StartTime'];
        $_res['end_time'] = $params['EndTime'];

        $_res['batch_list']['gift_id'] = json_encode($_giftCodeArr);
        foreach ($_giftCodeArr as $tmpGifCode) {
            $_res['batch_list']['recipients'] = json_encode([]);
        }

        return $_res;
        /*
         "content":
            {
                "batch_id": 'DDFSF12313'(批次号),
                "count":321321,(总数),
                "has_active":123,（已经激活数）,
                "has_used_num":123,(玩家已兑换数),
                'name': "新手大礼包",(名字)
                "limit": 1, （1表示只有一个帐号领取，0表示多个帐号可以领取）
                "is_active": "1",（是否激活了）
                'can_use': '1',(启动为1禁用为0)
                'start_time':'2013-02-12 08:01:50',
                'end_time':'2013-04-12 08:01:50',
                "batch_list" :
                [
                    {
                    'gift_id': "fdafdaf"，（礼包id）
                   "recipients":
                        [
                            {
                            'area'（全服）:'all','channel'（渠道）:'XXX','time'（领取时间）:'2013-03-12','user_id'（邀请码）:'123132','user_name'（玩家角色名）:'321321','can_use'（是否启用）:1
                            },
                            {
                        'area':'all','channel':'XXX','time':'2013-03-12','user_id':'123132','user_name':'321321','can_use':1
                            }
                        ](礼包领取人)
                    }，
                .......
                ]
            }
         */
    }

    /**
     * 获取一批次的礼包码
     * @param $params
     * @return array
     * @throws SzException
     */
    public function getBatchGiftCode($params)
    {
        /*
            "params": {
                "batch"(批次号):"DDFSF12313"
                }
            }
         */
        $_res = array();
        $batch = $params['batch'];

        /** @var GmBatchVo $_gmBatchVo */
        list($_gmBatchVo, $_giftCodeArr) = $this->getGiftCodeList($batch);

        $_res['batch_id'] = $batch;
        $_res['count'] = $_gmBatchVo->getCount();
        $_res['has_active'] = $_gmBatchVo->getUsedCount();
        $_res['has_used_num'] = $_gmBatchVo->getUsedCount();
        $_res['name'] = $_gmBatchVo->getName();
        $_res['limit'] = $_gmBatchVo->getGiftType();
        $_res['is_active'] = '1';
        $_res['can_use'] = $_gmBatchVo->getUsable();
        $_res['batch_list'] = array();
        $_res['start_time'] = date("Y-m-d H:i:s", $_gmBatchVo->getCreateTime());
        $_res['end_time'] = date("Y-m-d H:i:s", $_gmBatchVo->getExpiryTime());

        $batch_list = array();
        foreach ($_giftCodeArr as $key => $value) {
            /**
             * @var GmGiftCodeInfoVoList $_gmGiftCodeInfoVoList
             * @var GmGiftCodeInfoVo $_gmGiftCodeInfoVo
             */
            $_gmGiftCodeInfoVoList = $value;
            $_obj = array();
            $_obj['gift_id'] = $key;
            $_recipients = array();
            foreach ($_gmGiftCodeInfoVoList->toArray() as $userId => $gmGiftCodeInfoVo) {
                $_gmGiftCodeInfoVo = $_gmGiftCodeInfoVoList->getElement($userId);
                $_giftCodeInfo = array();
                $_giftCodeInfo['area'] = 'all';
                $_giftCodeInfo['channel'] = $_gmGiftCodeInfoVo->getChannel();
                $_giftCodeInfo['time'] = date("Y-m-d H:i:s", $_gmGiftCodeInfoVo->getReceiveTime());
                $_giftCodeInfo['user_id'] = $_gmGiftCodeInfoVo->getTargets();
                $_giftCodeInfo['user_name'] = $_gmGiftCodeInfoVo->getUserName();
                $_giftCodeInfo['can_use'] = 1;
                $_recipients[] = $_giftCodeInfo;
            }
            $_obj['recipients'] = ($_recipients);
            $batch_list[] = $_obj;
        }
        $_res['batch_list'] = json_encode($batch_list);

        return $_res;
        /*
         "content":
            {
                "batch_id": 'DDFSF12313'(批次号),
                "count":321321,(总数),
                "has_active":123,（已经激活数）,
                "has_used_num":123,(玩家已兑换数),
                'name': "新手大礼包",(名字)
                "limit": 1, （1表示只有一个帐号领取，0表示多个帐号可以领取）
                "is_active": "1",（是否激活了）
                'can_use': '1',(启动为1禁用为0)
                'start_time':'2013-02-12 08:01:50',
                'end_time':'2013-04-12 08:01:50',
                "batch_list" :
                [
                    {
                    'gift_id': "fdafdaf"，（礼包id）
                   "recipients":
                        [
                            {
                            'area'（全服）:'all','channel'（渠道）:'XXX','time'（领取时间）:'2013-03-12','user_id'（邀请码）:'123132','user_name'（玩家角色名）:'321321','can_use'（是否启用）:1
                            },
                            {
                        'area':'all','channel':'XXX','time':'2013-03-12','user_id':'123132','user_name':'321321','can_use':1
                            }
                        ](礼包领取人)
                    }，
                .......
                ]
            }
         */
    }

    /**
     * 变更礼包码的信息
     * @param $params
     * @return array
     * @throws SzException
     */
    public function changeBatchGiftCodeInfo($params)
    {
        /*
            "params": {
                "batch"(批次号):"DDFSF12313"，
                'can_use': '1',(启动为1禁用为0)
                }
         */
        $_res = array();
        $batch = $params['batch'];
        $can_use = $params['can_use'];

        /** @var GmBatchVoList $_gmBatchVoList */
        $_gmBatchVoList = SzPersister::get()->getVoList(0, GameConst::ORM_NAME_GM_TOOLS_BATCH);
        /** @var GmBatchVo $_gmBatchVo */
        $_gmBatchVo = $_gmBatchVoList->getElement($batch, false);
        if (!$_gmBatchVo) {
            throw new SzException(25015);
        }
        $_gmBatchVo->setUsable($can_use);
        $_gmBatchVoList->updateElement($batch, $_gmBatchVo);
        SzPersister::get()->setVoList($_gmBatchVoList);

        $_res['batch'] = $batch;
        $_res['can_use'] = $can_use;
        return $_res;
        /*
            "content": {
                  "batch"(批次号):"DDFSF12313"，
                  'can_use': '1',(启动为1禁用为0)
             }
         */
    }

    /**
     * @param $userId int 用户ID
     * @param $giftCode string 礼包码
     * @return int 返回状态 1：成功，2：过期或不存在， 3：礼包码已被使用，4：重复领用， 5：领取失败，6.同批次重复领用
     */
    public function receiveGiftCodeReward($userId, $giftCode)
    {
        $batchArr = UserService::get()->getInfo($userId, GameConst::USER_INFO_TYPE_GIFT_CODE_BATC);
        $_batchId = $this->parseGiftCode($giftCode);
        if (in_array($_batchId, $batchArr)) {
            return 6;
        }
        /** @var GmBatchVoList $_gmBatchVoList */
        $_gmBatchVoList = SzPersister::get()->getVoList(0, GameConst::ORM_NAME_GM_TOOLS_BATCH);
        /** @var GmBatchVo $_gmBatchVo */
        $_gmBatchVo = $_gmBatchVoList->getElement($_batchId, false);
        if (!$_gmBatchVo) return 2;
        if ($_gmBatchVo->getUsable() == 0) return 2;
        if (GameService::get()->getSysTime() > $_gmBatchVo->getExpiryTime()) return 2;

        /** @var GmGiftCodeVoList $_gmGiftCodeVoList */
        $_gmGiftCodeVoList = SzPersister::get()->getVoList($_batchId, GameConst::ORM_NAME_GM_TOOLS_GIFT_CODE);
        /** @var GmGiftCodeVo $_gmGiftCodeVo */
        $_gmGiftCodeVo = $_gmGiftCodeVoList->getElement($giftCode, false);
        if ($_gmGiftCodeVo->getIsUsed() && $_gmBatchVo->getGiftType() == 1) return 3;

        /** @var GmGiftCodeInfoVoList $_gmGiftCodeInfoVoList */
        $_gmGiftCodeInfoVoList = SzPersister::get()->getVoList($giftCode, GameConst::ORM_NAME_GM_TOOLS_GIFT_CODE_INFO);
        /** @var GmGiftCodeInfoVo $_gmGiftCodeInfoVo */
        $_gmGiftCodeInfoVo = $_gmGiftCodeInfoVoList->getElement($userId, false);
        if ($_gmGiftCodeInfoVo) return 4;

        $channel = UserService::get()->getInfo($userId, GameConst::USER_INFO_TYPE_GAME_ID);
        $targets = FriendService::get()->getFriendsCode($userId)->getFriendCode();
        SzLogger::get()->debug('receiveGiftCodeReward -----------------------------------------------$targets=' . $targets);
        $userName = UserService::get()->getTownName($userId);
        $this->createGiftCodeInfoVo($giftCode, $userId, $channel, $targets, $userName, GameService::get()->getSysTime());

        $_gmGiftCodeVo->setIsUsed(1);
        $_gmGiftCodeVoList->updateElement($giftCode, $_gmGiftCodeVo);
        SzPersister::get()->setVoList($_gmGiftCodeVoList);

        $_usedCount = $_gmBatchVo->getUsedCount();
        $_usedCount += 1;
        $_gmBatchVo->setUsedCount($_usedCount);
        $_gmBatchVoList->updateElement($_batchId, $_gmBatchVo);
        SzPersister::get()->setVoList($_gmBatchVoList);

        $_content = GameService::get()->getLanguageMsg($userId, GameConst::LANGUAGE_CONFIG_SETTING_TXT9_MAIL);

        $batchArr[] = $_batchId;
        UserService::get()->updateProfileInfo($userId, GameConst::USER_INFO_TYPE_GIFT_CODE_BATC, $batchArr);
        return 1;
    }

    /**
     * 生成礼包码
     * @param $name
     * @param $comment
     * @param $giftType
     * @param $createTime
     * @param $expiryTime
     * @param $items
     * @param $usable
     * @param $count
     * @param $usedCount
     * @returns array
     */
    public function generateGiftCode($name, $comment, $giftType, $createTime, $expiryTime, $items, $usable, $count, $usedCount)
    {
        $_giftCodeArr = array();
        $_batchId = $this->generateBatchId();
        $_gmGiftCodeVoList = SzPersister::get()->getVoList($_batchId, GameConst::ORM_NAME_GM_TOOLS_GIFT_CODE);
        SzLogger::get()->debug("--------" . var_export($_gmGiftCodeVoList, true) . "----");
        $this->createBatchVo($_batchId, $name, $comment, $giftType, $createTime, $expiryTime, $items, $usable, $count, $usedCount);
        for ($i = 0; $i < $count; $i++) {
            $_giftCode = $this->buildGiftCode($_batchId);
            $this->createGiftCodeVo($_batchId, $_giftCode, 0, $_gmGiftCodeVoList);
            $_giftCodeArr[] = $_giftCode;
            SzLogger::get()->debug("$i");
        }
        SzPersister::get()->setVoList($_gmGiftCodeVoList);
        return array($_batchId, $_giftCodeArr);
    }

    /**
     * 获取一个批次的礼包码
     * @param $batchId
     * @returns array
     */
    public function getGiftCodeList($batchId)
    {
        $_giftCodeInfoArr = array();
        /** @var GmBatchVoList $_gmBatchVoList */
        $_gmBatchVoList = SzPersister::get()->getVoList(0, GameConst::ORM_NAME_GM_TOOLS_BATCH);
        /** @var GmBatchVo $_gmBatchVo */
        $_gmBatchVo = $_gmBatchVoList->getElement($batchId);

        /** @var GmGiftCodeVoList $_gmGiftCodeVoList */
        $_gmGiftCodeVoList = SzPersister::get()->getVoList($batchId, GameConst::ORM_NAME_GM_TOOLS_GIFT_CODE);
        foreach ($_gmGiftCodeVoList->toArray() as $key => $value) {
            /** @var GmGiftCodeVo $_gmGiftCodeVo */
            $_gmGiftCodeVo = $_gmGiftCodeVoList->getElement($key);
            if ($_gmGiftCodeVo->getIsUsed() == 0) continue;
            /** @var GmGiftCodeInfoVoList $_gmGiftCodeInfoVoList */
            $_gmGiftCodeInfoVoList = SzPersister::get()->getVoList($_gmGiftCodeVo->getGiftCode(), GameConst::ORM_NAME_GM_TOOLS_GIFT_CODE_INFO);
            $_giftCodeInfoArr[$_gmGiftCodeVo->getGiftCode()] = $_gmGiftCodeInfoVoList;
        }
        return array($_gmBatchVo, $_giftCodeInfoArr);
    }

    public function buildGiftCode($batchId)
    {
        $_suffix = $this->generateGiftCodeSuffix();
        return $batchId . $_suffix;
    }

    public function parseGiftCode($giftCode)
    {
        return substr($giftCode, 0, 6);
    }

    /**
     * @param $batchId string
     * @param $name int
     * @param $comment string
     * @param $giftType int
     * @param $createTime int
     * @param $expiryTime int
     * @param $items array
     * @param $usable int
     * @param $count int
     * @param $usedCount int
     */
    public function createBatchVo($batchId, $name, $comment, $giftType, $createTime, $expiryTime, $items, $usable, $count, $usedCount)
    {
        /** @var GmBatchVoList $_gmBatchVoList */
        $_gmBatchVoList = SzPersister::get()->getVoList(0, GameConst::ORM_NAME_GM_TOOLS_BATCH);
        /** @var GmBatchVo $_gmBatchVo */
        $_gmBatchVo = new GmBatchVo(
            $batchId,
            0,
            $name,
            $comment,
            $giftType,
            $createTime,
            $expiryTime,
            json_encode($items),
            $usable,
            $count,
            $usedCount,
            true
        );
        $_gmBatchVoList->addElement($_gmBatchVo);
        $_gmBatchVoList->setElement($batchId, $_gmBatchVo);
        SzPersister::get()->setVoList($_gmBatchVoList);
    }

    public function createGiftCodeVo($batchId, $giftCode, $isUsed, &$_gmGiftCodeVoList)
    {
        /** @var GmGiftCodeVoList $_gmGiftCodeVoList */
        if (!$_gmGiftCodeVoList) {
            SzLogger::get()->debug("------------------is empty------------------");
            $_gmGiftCodeVoList = SzPersister::get()->getVoList($batchId, GameConst::ORM_NAME_GM_TOOLS_GIFT_CODE);
        }
        /** @var GmGiftCodeVo $_gmGiftCodeVo */
        $_gmGiftCodeVo = new GmGiftCodeVo(
            $batchId,
            $giftCode,
            $isUsed,
            true
        );
        $_gmGiftCodeVoList->addElement($_gmGiftCodeVo);
        $_gmGiftCodeVoList->setElement($giftCode, $_gmGiftCodeVo);
    }

    public function createGiftCodeInfoVo($giftCode, $userId, $channel, $targets, $userName, $receiveTime)
    {
        /** @var GmGiftCodeInfoVoList $_gmGiftCodeInfoVoList */
        $_gmGiftCodeInfoVoList = SzPersister::get()->getVoList($giftCode, GameConst::ORM_NAME_GM_TOOLS_GIFT_CODE_INFO);
        /** @var GmGiftCodeInfoVo $_gmGiftCodeInfoVo */
        $_gmGiftCodeInfoVo = new GmGiftCodeInfoVo(
            $giftCode,
            $userId,
            $channel,
            $targets,
            $userName,
            $receiveTime,
            true
        );
        $_gmGiftCodeInfoVoList->addElement($_gmGiftCodeInfoVo);
        $_gmGiftCodeInfoVoList->setElement($userId, $_gmGiftCodeInfoVo);
        SzPersister::get()->setVoList($_gmGiftCodeInfoVoList);
    }
}